package main.java.pers.seg.model.utils;

import static main.java.pers.seg.model.constants.ObjectConstants.*;
import main.java.pers.seg.model.constants.PathConstants;
import static main.java.pers.seg.model.utils.JudgeUtils.*;
import static main.java.pers.seg.model.utils.ListUtils.scanActivity;
import static main.java.pers.seg.model.utils.StringUtils.addBlank;
import static main.java.pers.seg.model.utils.FlowUtils.getInteractionFlow;
import static main.java.pers.seg.model.utils.FlowUtils.getTargetInFlow;
import static main.java.pers.seg.model.utils.StringUtils.isScreen;

import main.java.pers.seg.model.constants.PathConstants;
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class FileUtils {

    private static String tempFilter = "";

    private static final String corePattern = "#//Core\\S{0,}";
    private static final String extPattern = "#//Extensions\\S{0,}";

    private static int index = -1;

    private static String type = "";

    public static Element gatorroot;

    public static  Element ifmlroot;

    public static int menuCount = 1;


    public static void readTreeStructure() {
        SAXReader reader = new SAXReader();
        //读取文件 转换成Document
        try {
            Document document = (Document) reader.read(new File(PathConstants.GEN_TEMP_HOME));
            Document doc = ReadSchema();
            ifmlroot = doc.getRootElement().addElement("interactionFlowModel");

            //获取根节点元素
            gatorroot = document.getRootElement();
            scanActivity(gatorroot);
            //遍历
            listNodes(gatorroot,ifmlroot);
            doc.getRootElement().addElement("domainModel");
            //用于格式化xml内容和设置头部标签
            OutputFormat format = OutputFormat.createPrettyPrint();
            //设置xml文档的编码为utf-8
            format.setEncoding("ASCII");
            Writer out;
            //创建一个输出流对象
            out = new FileWriter(PathConstants.GEN_IFML_HOME);
            //创建一个dom4j创建xml的对象
            XMLWriter writer = new XMLWriter(out, format);
            //调用write方法将doc文档写到指定路径
            writer.write(doc);
            writer.close();
            System.out.println("生成XML文件成功");
            readMenu();


        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try{
            getTargetInFlow();
            Document document2 = (Document) reader.read(new File(PathConstants.GEN_IFML_HOME));
            //获取根节点元素
            Element ifmlroot2 = document2.getRootElement();
            modify(ifmlroot2);
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("ASCII");
            Writer out;
            //创建一个输出流对象
            out = new FileWriter(PathConstants.GEN_IFML_HOME);
            XMLWriter writer = new XMLWriter(out, format);
            writer.write(document2);
            writer.close();
            HeadersUtils.start(PathConstants.GEN_IFML_HOME);
            System.out.println("修改XML文件成功");
        }catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();

        }

    }

    /**
     * 替换掉原来的inInteractionFlows
     * @param ifmlnode
     */
    public static void modify(Element ifmlnode) {
        List<Attribute> list = ifmlnode.attributes();
        if (ifmlnode.getName().equals("interactionFlowModelElements")) {
            index++;

            if(ifmlnode.attribute("inInteractionFlows")!=null
                    && isScreen(ifmlnode)){
                Attribute attribute1 = ifmlnode.attribute("inInteractionFlows");
                String result = getInteractionFlow(index);
                if(result != ""){
                    attribute1.setValue(result);
                }
            }
        }
        Iterator<Element> ifmliterator = ifmlnode.elementIterator();

        while(ifmliterator.hasNext()){
            Element e = ifmliterator.next();
            modify(e);
        }
    }
    public static void listNodes(Element gatornode , Element ifmlnode){
        //首先获取当前节点的所有属性节点
        List<Attribute> list = gatornode.attributes();

        if (gatornode.getName().equals("Activity") || gatornode.getName().equals("OtherWindow")
                || gatornode.getName().equals("Fragment") || gatornode.getName().equals("Dialog")) {
            ifmlnode = activity(gatornode, ifmlnode);
        } else if (gatornode.getName().equals("View")) {
            ifmlnode = view(gatornode, ifmlnode);
            //需要处理特殊情况
            if (gatornode.attributeValue("type").equals("android.support.v7.widget.RecyclerView")) {
                type = "android.support.v7.widget.RecyclerView";
            }
        } else if (gatornode.getName().equals("EventAndHandler")) {
            ifmlnode = eventAndHandler(gatornode, ifmlnode, type);
        } else if (gatornode.getName().equals("Transfer")) {

            ifmlnode = transfer(gatornode, ifmlnode);
            if (type.equals("android.support.v7.widget.RecyclerView")) {

                type = "";
            }
        }
        Iterator<Element> gatoriterator = gatornode.elementIterator();

        while(gatoriterator.hasNext()){
            Element e = gatoriterator.next();
            listNodes(e,ifmlnode);
        }
    }
    public static void readMenu(){
        SAXReader reader = new SAXReader();
        //读取文件 转换成Document
        try {
            Document document = (Document) reader.read(new File(PathConstants.GEN_TEMP_HOME));
            Document doc = (Document) reader.read(new File(PathConstants.GEN_IFML_HOME));

            //获取根节点元素对象
            Element root = document.getRootElement();
            //遍历
            listMenu(document, doc);


        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
    public static void listMenu(Document document,Document doc){
       while(document.selectSingleNode("/GUIHierarchy/View["+menuCount+"]")!=null){
           Element element = (Element)document.selectSingleNode("/GUIHierarchy/View["+menuCount+"]");
           String source = element.attributeValue("source");
           String type = element.attributeValue("type");
           Element ifmlElement = (Element) doc.selectSingleNode("/IFMLModel/interactionFlowModel/interactionFlowModelElements[@name='" + source + "']");
           Element element1 = eventAndHandler(ifmlElement, "ext:TouchEvent", "menu");
           transfer(element1,type,source);
           menuCount++;

       }
        OutputFormat format2 = OutputFormat.createPrettyPrint();
        format2.setEncoding("ASCII");
        Writer out2;
        //创建一个输出流对象
        try {
            out2 = new FileWriter(PathConstants.GEN_IFML_HOME);
            XMLWriter writer2 = new XMLWriter(out2, format2);
            writer2.write(doc);
            writer2.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取Uml文件
     */
    public static void readUml() {
        SAXReader reader = new SAXReader();
        //读取文件 转换成Document
        try {
            Document document = (Document) reader.read(new File(PathConstants.GEN_UML_HOME));
            //获取根节点元素对象
            Element root = document.getRootElement();
            //遍历
            listUmlNodes(root);

        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //traversal(umlmap);
    }

    /**
     * 遍历Uml文件的节点
     * @param node
     */
    public static void listUmlNodes(Element node){
        //首先获取当前节点的所有属性节点
        List<Attribute> list = node.attributes();
        if(node.getName().equals("packagedElement")) {
            umlmap.put(node.attributeValue("id"), node.attributeValue("name"));
        }
        Iterator<Element> iterator = node.elementIterator();
        while(iterator.hasNext()){
            Element e = iterator.next();
            listUmlNodes(e);
        }
    }

    /**
     * 读取Core文件
     */
    public static void readCore() {
        SAXReader reader = new SAXReader();
        //读取文件 转换成Document
        try {
            Document document = (Document) reader.read(new File(PathConstants.GEN_CORE_HOME));
            //获取根节点元素对象
            Element root = document.getRootElement();
            //遍历
            listCoreNodes(root);

        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //traversal(coremap);
    }

    /**
     * 遍历Core文件的节点
     * @param node
     */
    public static void listCoreNodes(Element node) {
        //首先获取当前节点的所有属性节点
        List<Attribute> list = node.attributes();
        //if (!node.getName().equals("eSubpackages") && !node.getName().equals("EPackage")) {
        if (node.getName().equals("eClassifiers") || node.getName().equals("eStructuralFeatures")) {
            for (Attribute attribute : list) {
                /*if (attribute.getName().equals("name")) {
                    tempCore = attribute.getValue();
                }*/
                /*if (attribute.getName().equals("eOpposite") || attribute.getName().equals("eSuperTypes") ||
                        attribute.getName().equals("eType")) {*/
                if (attribute.getName().equals("eSuperTypes")) {
                    // 创建 Pattern 对象
                    Pattern pattern1 = Pattern.compile(corePattern);
                    Pattern pattern2 = Pattern.compile(extPattern);
                    // 现在创建 matcher 对象
                    Matcher m1 = pattern1.matcher(attribute.getValue());
                    Matcher m2 = pattern2.matcher(attribute.getValue());

                    if (m1.matches()) {
                        coremap.put(node.attributeValue("name"), "core");
                    } else if (m2.matches()) {
                        coremap.put(node.attributeValue("name"), "ext");
                    }
                }
                // }
            }

        }
        Iterator<Element> iterator = node.elementIterator();
        while (iterator.hasNext()) {
            Element e = iterator.next();
            listCoreNodes(e);
        }
    }


    /**
     * 读取filter文件
     */
    public static void readFilter(){
        SAXReader reader = new SAXReader();
        //读取文件 转换成Document
        try {
            Document document = (Document) reader.read(new File(PathConstants.GEN_FILTER_HOME));
            //获取根节点元素对象
            Element root = document.getRootElement();
            //遍历
            listFilterNodes(root);

        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //traversal(filtermap);
    }

    /**
     * 遍历filter文件的节点
     * @param node
     */
    public static void listFilterNodes(Element node){
        //首先获取当前节点的所有属性节点
        List<Attribute> list = node.attributes();
        if(node.getName().equals("gname")){
            tempFilter = node.getTextTrim();
        }
        else if(node.getName().equals("iname")){
            filtermap.put(tempFilter,node.getTextTrim());
        }

        Iterator<Element> iterator = node.elementIterator();
        while(iterator.hasNext()){
            Element e = iterator.next();
            listFilterNodes(e);
        }
    }
    public static void ReadViewElements(){
        SAXReader reader = new SAXReader();
        //读取文件 转换成Document
        try {
            Document document = (Document) reader.read(new File(PathConstants.GEN_VELEMENT_HOME));
            //获取根节点元素对象
            Element root = document.getRootElement();
            //遍历
            listViewElements(root);

        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
    public static void listViewElements(Element node){
        //首先获取当前节点的所有属性节点
        List<Attribute> list = node.attributes();
        if(node.getName().equals("ViewContainer")){
            tempFilter = node.getTextTrim();
        }
        else if(node.getName().equals("iname")){
            filtermap.put(tempFilter,node.getTextTrim());
        }

        Iterator<Element> iterator = node.elementIterator();
        while(iterator.hasNext()){
            Element e = iterator.next();
            listViewElements(e);
        }
    }
    /**
     * 读取type文件
     */
    public static void ReadType(){
        SAXReader reader = new SAXReader();
        //读取文件 转换成Document
        try {
            Document document = (Document) reader.read(new File(PathConstants.GEN_TYPE_HOME));
            //获取根节点元素对象
            Element root = document.getRootElement();
            //遍历
            listTypeNodes(root);

        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //traversal(filtermap);
    }

    /**
     * 遍历type文件的节点
     * @param node
     */
    public static void listTypeNodes(Element node){
        //首先获取当前节点的所有属性节点
        List<Attribute> list = node.attributes();
    /*    if (node.getName().equals("ext")) {
            type = "ext";
        } else {
            type = "core";
        }*/
        if(node.getName().equals("class") && node.getParent().getName().equals("ext")){
            extmap.put(node.getTextTrim(),"ext");
        }else{
            coremap.put(node.getTextTrim(),"core");
        }

        Iterator<Element> iterator = node.elementIterator();
        while(iterator.hasNext()){
            Element e = iterator.next();
            listTypeNodes(e);
        }
    }

    /**
     * 创建ifml文件，填入schema信息
     *不使用常量变量，占用方法区内存。原因是不常用，
     * @return
     */
    public static Document ReadSchema() {
        //创建一个xml文档
        Document doc = DocumentHelper.createDocument();
        Element ifmlroot = doc.addElement("core:IFMLModel");
        ifmlroot.addAttribute("xmi:version", "2.0");
        ifmlroot.addAttribute("xmlns:xmi", "http://www.omg.org/XMI");
        ifmlroot.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
        ifmlroot.addAttribute("xmlns:core", "http://www.omg.org/spec/20130218/core");
        ifmlroot.addAttribute("xmlns:ext", "http://www.omg.org/spec/20130218/ext");
        ifmlroot.addAttribute("xmlns:uml", "http://www.eclipse.org/uml2/5.0.0/UML");
        ifmlroot.addAttribute("name", "Picker");
        return doc;
    }

    /**
     * 以字符串形式读取指定xml，替换掉不合法的特殊字符
     */
    public static void readFileToTemp(){
        File file = new File(PathConstants.GEN_XML_HOME);
        BufferedReader reader = null;
        String finalString="";
        try {
            if(file.exists()){
                //清除xml内容
                clearXml(PathConstants.GEN_XML_HOME);
            }
        reader = new BufferedReader(new FileReader(file));
        String tempString = null;
        // 一次读入一行，直到读入null为文件结束
        while ((tempString = reader.readLine()) != null) {
            int firstIndex=tempString.indexOf("<");
            int lastIndex=tempString.lastIndexOf(">");

            int blankNum = tempString.indexOf("<");//前面空格数量
            String temp =tempString.substring(firstIndex+1, lastIndex);//去掉首尾括号
            String s1 = temp.replace(">", "&gt;");
            String s2 = s1.replace("<", "&lt;");

            String blank = addBlank(s2, blankNum);
            finalString += blank + "<" + s2 + ">"+"\n";

        }
        contentToXml(PathConstants.GEN_TEMP_HOME,finalString);
        reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
    }

    /**
     * 向指定xml文件输入内容
     * @param filePath
     * @param content
     */
    public static void contentToXml(String filePath, String content) {
        try{
            BufferedWriter writer = new BufferedWriter(new FileWriter(new File(filePath),true));
            writer.write(content);
            writer.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 若存在temp.xml 清除文件内容
     * @param filePath
     */
    public static void clearXml(String filePath){
        FileOutputStream testfile = null;
        try {
            testfile = new FileOutputStream(PathConstants.GEN_TEMP_HOME);
            testfile.write(new String("").getBytes());
            testfile.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * 遍历map
     * @param map
     */
    public static void traversal(Map<String,String> map){
        Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<String, String> entry = iterator.next();
            System.out.println(entry.getKey()+"****"+entry.getValue());
        }
    }




}
